#include <dlfcn.h>
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>

// A helper likely to be inlined/optimized with -O2 -flto
static inline const char* choose_symbol(int v) {
    static const char s1[] = "fopen";
    static const char s2[] = "close";
    return (v & 1) ? s1 : s2;
}

__attribute__((visibility("default")))
int opt_dlsym_user(int seed) {
    void *h = dlopen(NULL, RTLD_NOW);
    if (!h) return -1;

    const char* s = choose_symbol(seed);

    // Force a store/load through the stack to simulate optimizer moves
    const char* tmp = s;
    __asm__ volatile("": : "r"(tmp) : "memory");

    // Store to stack and reload (compiler should emit STR/ LDR [sp, #imm])
    const char* reload;
    __asm__ volatile(
        "str %1, [sp, #16]\n\t"
        "ldr %0, [sp, #16]\n\t"
        : "=r"(reload)
        : "r"(tmp)
        : "memory");

    void* p = dlsym(h, reload);
    return p ? 0 : -2;
}
